#include "FreeRTOS.h" /* Must come first. */
#include "task.h"     /* RTOS task related API prototypes. */
#include "timers.h"   /* Software timer related API prototypes. */
#include "../board/sdk_project_config.h"
#include "log.h"
#include "math.h"

#define GPS        1
#define DS18B20    1
#define DHT11      1
#define OLED 1
#define UART_DEBUG 1
#define GPIO_READ  1
#define ESP8266    1

#if 1
#define MPU6050 1
#else
#define SGP30      0
#endif

#define PRODUCER_TASK_STACK_SIZE 1024
#define CONSUMER_TASK_STACK_SIZE 1024
#define NETWORK_TASK_STACK_SIZE  1024

#define PRODUCER_TASK_PRIORITY 2
#define CONSUMER_TASK_PRIORITY 1
#define NETWORK_TASK_PRIORITY  3

static TaskHandle_t PRODUCER_TASK_handler;
static TaskHandle_t CONSUMER_TASK_handler;
static TaskHandle_t NETWORK_TASK_handler;

#include "esp8266_eswin.h"
#include "ds18b20_eswin.h"
#include "dht11_eswin.h"
#include "sgp30_eswin.h"
#include "oled_eswin.h"
#include "gps_eswin.h"
#include "mpu6050_eswin.h"
#include "gpio_eswin.h"

typedef struct
{
    float accel_x;
    float accel_y;
    float accel_z;
    float temperature;
    float gyro_x;
    float gyro_y;
    float gyro_z;
} MPU6050_t;

typedef struct
{
    volatile uint32_t light_trigger_count;
    volatile uint32_t shock_trigger_count;
    volatile uint32_t open_count;  // 开门次数
    volatile uint32_t close_count; // 关门次数  float accel_x;
} Count_t;

typedef struct {
    UTC_TIME utc;    // UTC 时间
    float latitude;  // 纬度(分格式)
    uint8_t nshemi;  // 北纬/南纬,N:北纬;S:南纬
    float longitude; // 经度(分格式)
    uint8_t ewhemi;  // 东经/西经,E:东经;W:西经
    float altitude;  // 海拔高度(厘米)  ///////////////--------------------------
    float speed;     // 地面速率(米/时)
    // NMEA_SLMSG slmsg[12]; // 最多12颗卫星信息
} GPS_t;

typedef struct
{
    Count_t Count;
    GPS_t gps_data;
    MPU6050_t mpu6050_data;
    float Goods_Temperature;
    float AIR_Temperature;
    float AIR_Humidity;
    uint16_t CO2;
} SensorData_t;

SensorData_t Sensor_Data_Receive = {
    .Goods_Temperature = 27.5,
    .AIR_Temperature   = 0,
    .AIR_Humidity      = 0,
    .CO2               = 400};

/** task 1: PRODUCER_TASK */
void PRODUCER_TASK(void *pvParameters)
{

    char int2floatStr[40];
    status_t status;
    static uint32_t tick_ms = 0;
    if (tick_ms > 0x0FFFFFFF)
        tick_ms = 0;
#if DS18B20
    // 初始化DS18B20
    if (DS18B20_Init() != STATUS_SUCCESS) {
        log_debug("DS18B20 initialization failed!\n");
        // return;
    } else {
        log_debug("DS18B20 initialization success!\n");
    }

    // 设置分辨率为12位
    if (DS18B20_SetResolution(DS18B20_RESOLUTION_12BIT) != DS18B20_OK) {
        log_debug("Failed to set resolution!\n");
        // return;
    } else {
        log_debug("Successed to set resolution!\n");
    }

    ds18b20_data_t ds18b20_data;
#endif

#if DHT11

    // 初始化DHT11
    if (DHT11_Init() != STATUS_SUCCESS) {
        log_debug("DHT11 initialization failed!\n");
        return;
    }
    vTaskDelay(2000);
    dht11_data_t dht11_data;

#endif

#if SGP30
    // 初始化 SGP30
    SGP30_HandleTypeDef sgp30;
    SGP30_Status sgp30_status = SGP30_Init(&sgp30, INST_I2C_0, &g_stI2c0MasterState);

    if (sgp30_status != SGP30_SUCCESS) {
        log_debug("SGP30 initialization failed: 0x%X\r\n", sgp30_status);
        return;
    } else {
        log_debug("SGP30 Serial ID: 0x%X\r\n", sgp30.serialID);
        log_debug("SGP30 initialization success: 0x%X\r\n", sgp30_status);
    }

    // 初始化空气质量测量
    sgp30_status = SGP30_InitAirQuality(&sgp30);
    if (sgp30_status != SGP30_SUCCESS) {
        log_debug("Air quality init failed: 0x%X\r\n", sgp30_status);
        return;
    } else {
        log_debug("Air quality init success: 0x%X\r\n", sgp30_status);
    }
#endif

#if GPS
    nmea_msg gpsData;
    status = GPS_Init();

    if (status != STATUS_SUCCESS) {
        log_debug("GPS initialization failed\r\n");
    }

    log_debug("GPS module initialized\r\n");

#endif

#if MPU6050
    // 初始化 MPU6050
    mpu6050_handle_t mpu;
    OS_DelayMs(100); // 100ms 读取间隔

    status = MPU6050_Init(&mpu, INST_I2C_1, &g_stI2c1MasterState1);

    if (status != STATUS_SUCCESS) {
        log_err("MPU6050 initialization failed\n");
    }

    // 配置传感器 (2g, 250dps, 94Hz低通滤波)
    MPU6050_Config(&mpu, ACCEL_RANGE_2G, GYRO_RANGE_250DPS, DLPF_BW_94HZ);

    // 校准传感器 (采集100个样本)
    MPU6050_Calibrate(&mpu, 100);

#endif

#if GPIO_READ
    // 定义计数器
    volatile uint32_t light_trigger_count = 0; //光敏触发计数
    volatile uint32_t shock_trigger_count = 0; //震动触发计数
    volatile uint32_t open_count          = 0; // 开门次数
    volatile uint32_t close_count         = 0; // 关门次数

    // 定义上一次状态（初始化为无效值）
    uint8_t last_door_state  = 0xFF;
    uint8_t last_light_state = 0xFF;
    uint8_t last_shock_state = 0xFF;

    uint8_t current_light_state = 0; // 读取当前LIGHT状态（1=触发，0=未触发）

    uint8_t current_shock_state = 0; // 读取当前SHOCK状态（1=触发，0=未触发）

    uint8_t current_state = 1; // 读取当前门磁状态（1=开门, 0=关门）
#endif
    while (1) {
#if DS18B20
        if (tick_ms % 3000) {
        } else {
            ds18b20_error_t err = DS18B20_ReadTemperature(&ds18b20_data);
            if (err == DS18B20_OK && ds18b20_data.valid) {
                if (ds18b20_data.is_negative) {
                    log_debug("Temperature: -%d.%04d°C\n", ds18b20_data.temperature_integer, ds18b20_data.temperature_decimal);
                    sprintf(int2floatStr, "-%d.%04d", ds18b20_data.temperature_integer, ds18b20_data.temperature_decimal);
                } else {
                    log_debug("Temperature: %d.%04d°C\n", ds18b20_data.temperature_integer, ds18b20_data.temperature_decimal);
                    sprintf(int2floatStr, "%d.%04d", ds18b20_data.temperature_integer, ds18b20_data.temperature_decimal);
                }
                Sensor_Data_Receive.Goods_Temperature = atof(int2floatStr);
            } else {
                log_debug("DS18B20 read error: ");
                switch (err) {
                case DS18B20_ERROR_TIMEOUT:
                    log_debug("Timeout\n");
                    break;
                case DS18B20_ERROR_CHECKSUM:
                    log_debug("Checksum error\n");
                    break;
                case DS18B20_ERROR_NO_DEVICE:
                    log_debug("No device detected\n");
                    break;
                case DS18B20_ERROR_CONVERSION:
                    log_debug("Conversion timeout\n");
                    break;
                default:
                    log_debug("Unknown error\n");
                }
            }
        }
#endif

#if DHT11
        if (tick_ms % 2000) {
        } else {
            dht11_error_t err = DHT11_Read_Data(&dht11_data);
            if (err == DHT11_OK) {
                log_debug("Humidity: %d.%d %%\t", dht11_data.humidity_integer, dht11_data.humidity_decimal);
                //°C
                log_debug("Temperature: %d.%d C\n", dht11_data.temperature_integer, dht11_data.temperature_decimal);
                sprintf(int2floatStr, "%d.%d", dht11_data.temperature_integer, dht11_data.temperature_decimal);
                Sensor_Data_Receive.AIR_Temperature = atof(int2floatStr);
                sprintf(int2floatStr, "%d.%d", dht11_data.humidity_integer, dht11_data.humidity_decimal);
                Sensor_Data_Receive.AIR_Humidity = atof(int2floatStr);
            } else {
                log_debug("DHT11 read error: ");
                switch (err) {
                case DHT11_ERROR_TIMEOUT:
                    log_debug("Timeout\n");
                    break;
                case DHT11_ERROR_CHECKSUM:
                    log_debug("Checksum error\n");
                    break;
                case DHT11_ERROR_NO_RESPONSE:
                    log_debug("No response\n");
                    break;
                default:
                    log_debug("Unknown error\n");
                }
            }
        }

#endif
        if (tick_ms % 100) {
                } else {
        Sensor_Data_Receive.CO2++;
                }
#if SGP30
        if (tick_ms % 1000) {
        } else {
            // 测量空气质量
            sgp30_status = SGP30_MeasureAirQuality(&sgp30);
            if (sgp30_status == SGP30_SUCCESS) {
                log_debug("CO₂: %d ppm, TVOC: %d ppb\r\n", sgp30.CO2, sgp30.TVOC);
                Sensor_Data_Receive.CO2 = sgp30.CO2;
            } else {
                log_debug("Measurement failed: 0x%X\r\n", sgp30_status);
                Sensor_Data_Receive.CO2 = 400;
            }
        }
#endif

#if GPS
        if (tick_ms % 2000) {
        } else {
            // 读取 GPS 数据
            status = GPS_ReadData(&gpsData);
            if (status == STATUS_SUCCESS) {
                // 处理 GPS 数据
                log_debug("GPS Read Success code: 0x%x\r\n", status);
                log_debug("Time: %02d:%02d:%02d\r\n", gpsData.utc.hour, gpsData.utc.min, gpsData.utc.sec);
                Sensor_Data_Receive.gps_data.utc.hour = gpsData.utc.hour;
                Sensor_Data_Receive.gps_data.utc.min  = gpsData.utc.min;
                Sensor_Data_Receive.gps_data.utc.sec  = gpsData.utc.sec;
                log_debug(" Longitude: %d.%05d, Latitude: %d.%05d\r\n", gpsData.longitude / 100000, gpsData.longitude % 100000,
                          gpsData.latitude / 100000, gpsData.latitude % 100000);
                sprintf(int2floatStr, "%d.%05d", gpsData.longitude / 100000, gpsData.longitude % 100000);
                Sensor_Data_Receive.gps_data.longitude = atof(int2floatStr);
                sprintf(int2floatStr, "%d.%05d", gpsData.latitude / 100000, gpsData.latitude % 100000);
                Sensor_Data_Receive.gps_data.latitude = atof(int2floatStr);

                log_debug("ewhemi: %c, nshemi: %c\r\n",
                          gpsData.ewhemi, gpsData.nshemi);
                Sensor_Data_Receive.gps_data.ewhemi = gpsData.ewhemi;
                Sensor_Data_Receive.gps_data.nshemi = gpsData.nshemi;

                log_debug("Altitude: %d cm, Speed: %d m/s\r\n", gpsData.altitude, gpsData.speed / 60);
                sprintf(int2floatStr, "%d.0", gpsData.altitude);
                Sensor_Data_Receive.gps_data.altitude = atof(int2floatStr);
                sprintf(int2floatStr, "%d.0", gpsData.speed / 60);
                Sensor_Data_Receive.gps_data.speed = atof(int2floatStr);
                // Sensor_Data_Receive.gps_data.altitude = gpsData.altitude;
                // Sensor_Data_Receive.gps_data.speed    = gpsData.speed;
                log_debug("Satellites: %d in view, %d used\r\n", gpsData.svnum, gpsData.posslnum);
                // Sensor_Data_Receive.gps.svnum    = gpsData.svnum;
                // Sensor_Data_Receive.gps.posslnum = gpsData.posslnum;
            } else {
                log_debug("GPS Read failed code: 0x%x\r\n", status);
            }
        }
#endif

#if MPU6050
        if (tick_ms % 10) {
        } else {
            float pitch, roll;
            MPU6050_t data;
            memset(&data, 0, sizeof(MPU6050_t));
            // 读取加速度计数据
            if (MPU6050_ReadAccel(&mpu, &data.accel_x, &data.accel_y, &data.accel_z) == STATUS_SUCCESS) {
                log_debug("Accel: X=%.2fg, Y=%.2fg, Z=%.2fg\n", data.accel_x, data.accel_y, data.accel_z);
            }
            Sensor_Data_Receive.mpu6050_data.accel_x = data.accel_x;
            Sensor_Data_Receive.mpu6050_data.accel_y = data.accel_y;
            Sensor_Data_Receive.mpu6050_data.accel_z = data.accel_z;
            // 读取陀螺仪数据
            if (MPU6050_ReadGyro(&mpu, &data.gyro_x, &data.gyro_y, &data.gyro_z) == STATUS_SUCCESS) {
                log_debug("Gyro: X=%.2f°/s, Y=%.2f°/s, Z=%.2f°/s\n", data.gyro_x, data.gyro_y, data.gyro_z);
            }
            Sensor_Data_Receive.mpu6050_data.gyro_x = data.gyro_x;
            Sensor_Data_Receive.mpu6050_data.gyro_y = data.gyro_y;
            Sensor_Data_Receive.mpu6050_data.gyro_z = data.gyro_z;
            // 读取温度数据
            if (MPU6050_ReadTemperature(&mpu, &data.temperature) == STATUS_SUCCESS) {
                log_debug("Temperature: %.2f°C\n", data.temperature);
            }
            Sensor_Data_Receive.mpu6050_data.temperature = data.temperature;
#if 0
            //        CalculateAngles(data.accel_x, data.accel_y, data.accel_z, &pitch, &roll);
            pitch = safe_atan2f(data.accel_y, my_sqrtf(data.accel_x * data.accel_x + data.accel_z * data.accel_z)) * 180.0f / 3.1415926f;
            roll  = safe_atan2f(-data.accel_x, my_sqrtf(data.accel_y * data.accel_y + data.accel_z * data.accel_z)) * 180.0f / 3.1415926f;
            log_debug("%f,%f,%f,%f,%f,%f,%f,%f,%f\n", data.accel_x, data.accel_y, data.accel_z, data.gyro_x, data.gyro_y, data.gyro_z, data.temperature, pitch, roll);
#endif
        }
#endif

#if GPIO_READ
        // 读取当前LIGHT状态（1=触发，0=未触发）
        current_light_state = (PINS_DRV_ReadPins(LIGHT_PORT) >> LIGHT_PIN) & 0x01;

        // 读取当前SHOCK状态（1=触发，0=未触发）
        current_shock_state = (PINS_DRV_ReadPins(SHOCK_PORT) >> SHOCK_PIN) & 0x01;

        // 读取当前门磁状态（1=开门, 0=关门）
        current_state = (PINS_DRV_ReadPins(REED_PORT) >> REED_PIN) & 0x01;

        // 状态变化检测
        if (current_state != last_door_state) {
            // 添加去抖动延时（根据硬件调整时间）
            if (tick_ms % 5) {
            } else {
                // 重新读取确认状态
                current_state = (PINS_DRV_ReadPins(REED_PORT) >> REED_PIN) & 0x01;

                // 确认状态变化有效
                if (current_state != last_door_state) {
                    if (current_state == 1) { // 开门动作
                        open_count++;
                        log_info("Door OPENED. Total opens: %lu\r\n", open_count);
                    } else { // 关门动作
                        close_count++;
                        log_info("Door CLOSED. Total closes: %lu\r\n", close_count);
                    }
                    last_door_state = current_state; // 更新状态
                }
            }
        }

        // 检测LIGHT状态变化
        if (current_light_state != last_light_state) {
            // 去抖动延时
            if (tick_ms % 2) {
            } else {
                // 重新读取确认状态
                current_light_state = (PINS_DRV_ReadPins(LIGHT_PORT) >> LIGHT_PIN) & 0x01;

                // 确认状态变化有效
                if (current_light_state != last_light_state) {
                    if (current_light_state == 1) { // 触发状态
                        light_trigger_count++;
                        log_info("LIGHT triggered! Count: %lu\r\n", light_trigger_count);
                    }
                    last_light_state = current_light_state; // 更新状态
                }
            }
        }

        // 检测SHOCK状态变化
        if (current_shock_state != last_shock_state) {
            // 去抖动延时
            if (tick_ms % 2) {
            } else {
                // 重新读取确认状态
                current_shock_state = (PINS_DRV_ReadPins(SHOCK_PORT) >> SHOCK_PIN) & 0x01;

                // 确认状态变化有效
                if (current_shock_state != last_shock_state) {
                    if (current_shock_state == 1) { // 触发状态
                        shock_trigger_count++;
                        log_info("SHOCK triggered! Count: %lu\r\n", shock_trigger_count);
                    }
                    last_shock_state = current_shock_state; // 更新状态
                }
            }
        }

        Sensor_Data_Receive.Count.open_count          = open_count;
        Sensor_Data_Receive.Count.close_count         = close_count;
        Sensor_Data_Receive.Count.light_trigger_count = light_trigger_count;
        Sensor_Data_Receive.Count.shock_trigger_count = shock_trigger_count;

#endif
        vTaskDelay(10);
        tick_ms++;
    }
    vTaskDelete(PRODUCER_TASK_handler);
}

/** task 2: CONSUMER_TASK */
void CONSUMER_TASK(void *pvParameters)
{

#if OLED
    char OLED_Str[64];
    vTaskDelay(2000);
    OLED_Init();
    vTaskDelay(500);
#endif

    while (1) {
        PINS_DRV_TogglePin(PORTC, 28);
        vTaskDelay(1000);

#if OLED
        OLED_NewFrame();
        sprintf(OLED_Str, "卫星时间: %02d:%02d:%02d", Sensor_Data_Receive.gps_data.utc.hour, Sensor_Data_Receive.gps_data.utc.min, Sensor_Data_Receive.gps_data.utc.sec);
        OLED_PrintString(1, 0, OLED_Str, &font12x12, OLED_COLOR_NORMAL);
        sprintf(OLED_Str, "经度: %.5f, %c",
                Sensor_Data_Receive.gps_data.longitude, Sensor_Data_Receive.gps_data.ewhemi);
        OLED_PrintString(1, 13, OLED_Str, &font12x12, OLED_COLOR_NORMAL);
        sprintf(OLED_Str, "纬度: %.5f, %c",
                Sensor_Data_Receive.gps_data.latitude, Sensor_Data_Receive.gps_data.nshemi);
        OLED_PrintString(1, 13 + 13, OLED_Str, &font12x12, OLED_COLOR_NORMAL);
        //        sprintf(OLED_Str, "Altitude: %d cm, Speed: %d m/h", Sensor_Data_Receive.gps.altitude, Sensor_Data_Receive.gps.speed);
        sprintf(OLED_Str, (char *)"CO2:%dppm ", Sensor_Data_Receive.CO2);
        OLED_PrintString(1, 13 + 13 + 13, OLED_Str, &font12x12, OLED_COLOR_NORMAL);
        sprintf(OLED_Str, (char *)"温度:%03.1fC", Sensor_Data_Receive.AIR_Temperature); // 温度数据显示
        OLED_PrintString(1, 13 + 13 + 13 + 13, OLED_Str, &font12x12, OLED_COLOR_NORMAL);
        sprintf(OLED_Str, (char *)"湿度:%03.1f%%", Sensor_Data_Receive.AIR_Humidity); // 温度数据显示
        OLED_PrintString(64 + 1, 13 + 13 + 13 + 13, OLED_Str, &font12x12, OLED_COLOR_NORMAL);
        OLED_ShowFrame();
#endif

#if UART_DEBUG
        log_info("二氧化碳浓度:%dppm \r\n", Sensor_Data_Receive.CO2);
        log_info("物品温度:%04.2f℃  \r\n", Sensor_Data_Receive.Goods_Temperature);
        log_info("空气温度:%04.2f℃  \r\n", Sensor_Data_Receive.AIR_Temperature);
        log_info("空气湿度:%03.2f%%  \r\n", Sensor_Data_Receive.AIR_Humidity);
        log_info("加速度: X=%.2fg, Y=%.2fg, Z=%.2fg\r\n", Sensor_Data_Receive.mpu6050_data.accel_x, Sensor_Data_Receive.mpu6050_data.accel_y, Sensor_Data_Receive.mpu6050_data.accel_z);
        log_info("角速度: X=%.2f°/s, Y=%.2f°/s, Z=%.2f°/s\r\n", Sensor_Data_Receive.mpu6050_data.gyro_x, Sensor_Data_Receive.mpu6050_data.gyro_y, Sensor_Data_Receive.mpu6050_data.gyro_z);

#endif
        PINS_DRV_TogglePin(PORTC, 28);
        vTaskDelay(1000);
    }

    vTaskDelete(CONSUMER_TASK_handler);
}

/** task 3: NETWORK_TASK */
void NETWORK_TASK(void *pvParameters)
{

#if ESP8266
    if (ESP8266_Init() != ESP_OK) {
        // 初始化失败处理
        log_debug("Init fail\r\n");
    } else {
        PINS_DRV_TogglePin(PORTD, 14);
        vTaskDelay(1000);
    }
    if (ESP_ConnectToWiFi() != ESP_OK) {
        // WiFi连接失败
        log_debug("WiFi Connect fail\r\n");
    } else {
        PINS_DRV_TogglePin(PORTD, 14);
        vTaskDelay(1000);
    }
    vTaskDelay(4000);
    if (ESP_ConnectToTCPServer() != ESP_OK) {
        // TCP连接失败
        log_debug("TCP Connect fail\r\n");
    } else {
        PINS_DRV_TogglePin(PORTD, 14);
        vTaskDelay(1000);
    }

    // 测试
    char Send_String[128] = "!!CONNECT SUCCESS!!";
    ESP_SendString((uint8_t *)Send_String, strlen(Send_String));
    PINS_DRV_WritePin(PORTD, 14, 0);
#endif
    while (1) {
        static uint32_t tick_ms = 0;
        if (tick_ms > 0x0FFFFFFF)
            tick_ms = 0;
        PINS_DRV_WritePin(PORTD, 14, 1);
#if ESP8266
        if (tick_ms % 10) {
        } else {
            ESP_Send_MPU6050_Data(Sensor_Data_Receive.mpu6050_data.accel_x, Sensor_Data_Receive.mpu6050_data.accel_y, Sensor_Data_Receive.mpu6050_data.accel_z, Sensor_Data_Receive.mpu6050_data.gyro_x, Sensor_Data_Receive.mpu6050_data.gyro_y, Sensor_Data_Receive.mpu6050_data.gyro_z);
        }
        if (tick_ms % 50) {
        } else {
            sprintf(Send_String, "Time:%02d:%02d:%02d", Sensor_Data_Receive.gps_data.utc.hour, Sensor_Data_Receive.gps_data.utc.min, Sensor_Data_Receive.gps_data.utc.sec);
            ESP_SendString((uint8_t *)Send_String, strlen(Send_String));
        }
        if (tick_ms % 45) {
        } else {
            ESP_Send_Sensor_Data(Sensor_Data_Receive.AIR_Humidity, Sensor_Data_Receive.AIR_Temperature, Sensor_Data_Receive.Goods_Temperature, Sensor_Data_Receive.CO2);
        }

        if (tick_ms % 20) {
        } else {
            ESP_Send_Count_Data(Sensor_Data_Receive.Count.open_count, Sensor_Data_Receive.Count.close_count, Sensor_Data_Receive.Count.light_trigger_count, Sensor_Data_Receive.Count.shock_trigger_count);
        }
        if (tick_ms % 300) {
        } else {
            if (ESP_SendPing() == ESP_TIMEOUT) {
                if (ESP_ConnectToWiFi() != ESP_OK) {
                    // WiFi连接失败
                    log_debug("WiFi Connect fail\r\n");
                } else {
                    PINS_DRV_TogglePin(PORTD, 14);
                    vTaskDelay(1000);
                }
                vTaskDelay(4000);
                if (ESP_ConnectToTCPServer() != ESP_OK) {
                    // TCP连接失败
                    log_debug("TCP Connect fail\r\n");
                } else {
                    PINS_DRV_TogglePin(PORTD, 14);
                    vTaskDelay(1000);
                }
            }
        }
        if (tick_ms % 100) {
        } else {
            ESP_Send_GPS_Data(Sensor_Data_Receive.gps_data.longitude, Sensor_Data_Receive.gps_data.latitude);
        }
#endif
        tick_ms++;
        vTaskDelay(100);
        PINS_DRV_WritePin(PORTD, 14, 0);
    }
    vTaskDelete(NETWORK_TASK_handler);
}

void UART_Config_Init(void)
{
    UART_DRV_Init(INST_UART_2, &g_stUartState_2, &g_stUart2UserConfig0);
    UART_DRV_Init(INST_UART_4, &g_stUartState_4, &g_stUart4UserConfig0);
    setLogPort(2);
    log_debug("DEBUG SERIAL OPENED\r\n");
}

void I2C_Config_Init()
{
    status_t initStatus = I2C_DRV_MasterInit(INST_I2C_0, &g_stI2c0MasterUserConfig0, &g_stI2c0MasterState);
    if (initStatus != STATUS_SUCCESS) {
        log_debug("I2C0 0 initialization fail: %d\n", initStatus);
    } else {
        log_debug("I2C0 0 initialization success: %d\n", initStatus);
    }

    PDMA_DRV_Init(&g_stPdmaState0, &g_stPdma0UserConfig0, g_stPdma0ChnStateArray,
                  g_stPdma0ChannelConfigArray, PDMA_CHANNEL_CONFIG_COUNT);

#if SGP30
    initStatus = I2C_DRV_MasterInit(INST_I2C_1,
                                    &g_stI2c1MasterUserConfig0, &g_stI2c1MasterState0);
    if (initStatus != STATUS_SUCCESS) {
        log_debug("I2C1 0 initialization fail: %d\n", initStatus);
    } else {
        log_debug("I2C1 0 initialization success: %d\n", initStatus);
    }
#endif
#if MPU6050
    initStatus = I2C_DRV_MasterInit(INST_I2C_1,
                                    &g_stI2c1MasterUserConfig1, &g_stI2c1MasterState1);
    if (initStatus != STATUS_SUCCESS) {
        log_debug("I2C1 1 initialization fail: %d\n", initStatus);
    } else {
        log_debug("I2C1 1 initialization success: %d\n", initStatus);
    }
#endif
}

void PIN_Config_Init()
{
    PINS_DRV_Init(NUM_OF_CONFIGURED_PINS, g_stPinmuxConfigArr);
}

void MainStartTask(void)
{
    BaseType_t result;

    taskENTER_CRITICAL();

    result = xTaskCreate((TaskFunction_t)PRODUCER_TASK, (const char *)"PRODUCER_TASK",
                         (uint16_t)PRODUCER_TASK_STACK_SIZE, (void *)NULL,
                         (UBaseType_t)PRODUCER_TASK_PRIORITY,
                         (TaskHandle_t *)&PRODUCER_TASK_handler);
    if (result != pdPASS) {
        log_err("log_test1 task create err\n");
    }

    result = xTaskCreate((TaskFunction_t)CONSUMER_TASK, (const char *)"CONSUMER_TASK",
                         (uint16_t)CONSUMER_TASK_STACK_SIZE, (void *)NULL,
                         (UBaseType_t)CONSUMER_TASK_PRIORITY,
                         (TaskHandle_t *)&CONSUMER_TASK_handler);
    if (result != pdPASS) {
        log_err("log_test2 task create err\n");
    }

    result = xTaskCreate((TaskFunction_t)NETWORK_TASK, (const char *)"NETWORK_TASK",
                         (uint16_t)NETWORK_TASK_STACK_SIZE, (void *)NULL,
                         (UBaseType_t)NETWORK_TASK_PRIORITY,
                         (TaskHandle_t *)&NETWORK_TASK_handler);
    if (result != pdPASS) {
        log_err("log_test3 task create err\n");
    }

    taskEXIT_CRITICAL();
    vTaskStartScheduler();
}

/**
 * @brief The main function for the project.
 */
int main(void)
{
    CLOCK_SYS_Init(g_pstClockManConfigsArr[0]);
    PIN_Config_Init();
    UART_Config_Init();
    I2C_Config_Init();

    MainStartTask();
    /* Endless loop. */
    while (1) {
        OS_DelayMs(100);
    }
}
